package com.ruoyi.mall.product.service;

import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.mall.product.domain.entity.PmsCategory;
import com.ruoyi.mall.product.domain.service.IPmsCategoryService;
import com.ruoyi.mall.product.domain.vo.TreeSelect;
import com.ruoyi.mall.product.spring.cache.AppCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @program: zqs-mall
 * @description:
 * @author: Mr.Zhang
 * @create: 2022-05-30 11:10
 **/
@Service
public class PmsCategoryAppService {
    @Autowired
    private IPmsCategoryService pmsCategoryService;

    @Autowired
    private RedisService redisService;


    /**
     * 查询商品三级分类
     *
     * @param id 商品三级分类主键
     * @return 商品三级分类
     */

    public PmsCategory selectPmsCategoryById(Long id) {
        return pmsCategoryService.selectPmsCategoryById(id);
    }

    /**
     * 查询商品三级分类列表
     *
     * @param pmsCategory 商品三级分类
     * @return 商品三级分类
     */
    public List<PmsCategory> selectPmsCategoryList(PmsCategory pmsCategory) {
        return pmsCategoryService.selectPmsCategoryList(pmsCategory);
    }

    /**
     * 新增商品三级分类
     *
     * @param pmsCategory 商品三级分类
     * @return 结果
     */
    public int insertPmsCategory(PmsCategory pmsCategory) {
        return pmsCategoryService.insertPmsCategory(pmsCategory);
    }

    /**
     * 修改商品三级分类
     *
     * @param pmsCategory 商品三级分类
     * @return 结果
     */
    public int updatePmsCategory(PmsCategory pmsCategory) {
        return pmsCategoryService.updatePmsCategory(pmsCategory);
    }

    /**
     * 批量删除商品三级分类
     *
     * @param ids 需要删除的商品三级分类主键
     * @return 结果
     */
    public int deletePmsCategoryByIds(Long[] ids) {
        return pmsCategoryService.deletePmsCategoryByIds(ids);
    }

    /**
     * 删除商品三级分类信息
     *
     * @param id 商品三级分类主键
     * @return 结果
     */
    public int deletePmsCategoryById(Long id) {
        return pmsCategoryService.deletePmsCategoryById(id);
    }

    /**
     * 树形结构查询所有分类  TODO redis 产生堆外内存溢出异常 OutPfDirectMemoryError
     *  1.springboot2.0以后默认使用lettuce作为操作redis的客户端。他使用netty进行网络通信
     *  2.lettuce的bug导致netty堆外内存溢出 -Xmx 300m netty如果没有指定堆外内存，默认使用-Xmx300m作为堆外内存
     *   可以通过-Dio.netty.maxDirectMemory进行设置
     *  解决方案: 不能使用-Dio.netty.maxDirectMemory只去调大堆外内存
     *  1. 升级lettuce客户端 2.换成Jredis客户端  TODO 这个问题已经解决
     *
     * @return
     */
    public List<TreeSelect> listWithTree() {

        //解决高并发下缓存问题
        //1. 空结果缓存:解决缓存穿透
        //2. 设置过期时间(加随机值): 解决雪崩
        //3. 加锁: 解决缓存击穿


        List<TreeSelect> list = redisService.getCacheList("categoryJson");
        List<TreeSelect> selects = pmsCategoryService.listWithTree();
        if(StringUtils.isEmpty(list)){
            redisService.setCacheList("categoryJson",selects);
            redisService.expire("categoryJson",1, TimeUnit.DAYS);
            return selects;
        }
        return list;

    }

    /**
     * 批量删除
     * @param ids 分类id集合
     */
    public void deleteCategoryByIds(List<Long> ids) {
        //TODO 检查当前删除的菜单，是否被别的地方引用
        //逻辑删除
        pmsCategoryService.deleteCategoryByIds(ids);
    }

    /**
     * 批量更新
     * @param asList
     * @return
     */
    public boolean updateBatchById(List<PmsCategory> asList) {

        return pmsCategoryService.updateBatchById(asList);
    }


    /**
     * 获取三级分类路径
     * @param categoryId
     * @return
     */
    public Long[] findCategoryPath(Long categoryId) {
        return pmsCategoryService.findCategoryPath(categoryId);
    }
}
